package com.trigsoft.applist;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.trigsoft.utils.PrefUtil;

public class TaskAdapter extends BaseAdapter
{
	private class LoadTask extends AsyncTask<Void, Void, Bitmap>
	{
		private ImageView view;
		private byte[] blob;
		private String name;

		public LoadTask(ImageView view, Cursor cursor, String name)
		{
			this.view = view;
			blob = cursor.getBlob(cursor.getColumnIndex(DBHelper.KEY_ICON));
			this.name = name;
		}

		@Override
		protected Bitmap doInBackground(Void... arg0)
		{
			// TODO Auto-generated method stub
			return BitmapFactory.decodeByteArray(blob, 0, blob.length);
		}

		@Override
		protected void onPostExecute(Bitmap bitmap)
		{
			IconCache.icons.put(name, bitmap);
			view.setImageBitmap(bitmap);
		}
	}

	/*	public boolean onTouch(View arg0, MotionEvent event)
		{
			// TODO Auto-generated method stub
			switch (event.getAction())
			{
			case MotionEvent.ACTION_DOWN:
				x = event.getRawX();
				y = event.getRawY();
				break;
			}
			return false;
		}

		public void showDialog(View v, int x, int y)
		{
			//Integer myPosition = (Integer) v.getTag();
			//Message m = getItem(new Integer(myPosition));
			replyDialog = new ReplyDialog(mCtx, 1, x, y);
			replyDialog.show();
		}
		
		public boolean onLongClick(View v)
		{
			// TODO Auto-generated method stub
			
			//showDialog(v, (int)x - screenWidth / 2 + 40, (int)y
			//		- screenHeight / 2 - 60);
			new ContextDialog(mCtx, v, 1, this).show();
			return true;
		}*/
	static class Wrapper
	{
		ImageView icon;
		TextView text;
	}

	Activity mCtx;
	PackageManager pm;
	ReplyDialog replyDialog;

	float x = 0;
	float y = 0;
	//private final static String[] exceptionList = {"kz.mek.DialerOne", "com.trigsoft.applist",
	//		"com.android.packageinstaller"};
	private List<ActivityManager.RecentTaskInfo> taskList = new ArrayList<ActivityManager.RecentTaskInfo>(10);

	private List<ResolveInfo> infoList = new ArrayList<ResolveInfo>(10);

	private List<App> pkgList;

	private NotInRecent nir;

	public TaskAdapter(Activity context)
	{
		// TODO Auto-generated constructor stub

		mCtx = context;

		nir = new NotInRecent(mCtx);

		pm = mCtx.getPackageManager();

		ActivityManager manager = (ActivityManager) mCtx.getSystemService(Context.ACTIVITY_SERVICE);
		//Have to use 0 to ignore something not available for users. This is not stated in SDK. But can be
		//found in https://android.git.kernel.org/?p=platform/frameworks/policies/base.git;a=blobdiff;f=phone/com/android/internal/policy/impl/RecentApplicationsDialog.java
		//API 11 has RECENT_IGNORE_UNAVAILABLE which has same result
		List<ActivityManager.RecentTaskInfo> tmpList = manager.getRecentTasks(20, 0);
		int size = tmpList.size();
		ExecutorService exec = Executors.newFixedThreadPool(size);
		ArrayList<Future<String>> results = new ArrayList<Future<String>>(size);
		for (ActivityManager.RecentTaskInfo task : tmpList)
		{
			if (results.size() < 10)
				results.add(exec.submit(new GetTask(task)));
		}

		for (Future<String> fs : results)
			try
			{
				fs.get();
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			} catch (ExecutionException e)
			{
				e.printStackTrace();
			} finally
			{
				exec.shutdown();
			}

		if (taskList.size() < 10 && PrefUtil.checkIntegrateStatistics(mCtx))
		{
			pkgList = new ArrayList<App>(10 - taskList.size());
			Cursor cursor = DBHelper.queryInCountInRecent();

			while (cursor.moveToNext() && pkgList.size() < 10 - taskList.size())
			{
				App app = new App(cursor);
				boolean toAdd = true;
				for (ActivityManager.RecentTaskInfo task : taskList)
				{
					if (app.getName().compareToIgnoreCase(task.baseIntent.getComponent().getClassName()) == 0)
					{
						toAdd = false;
						break;
					}
				}
				if (toAdd)
					pkgList.add(app);

			}
			Log.d("test", pkgList.toArray().toString());
		}
	}

	private class GetTask implements Callable<String>
	{
		private ActivityManager.RecentTaskInfo task;

		public GetTask(ActivityManager.RecentTaskInfo task)
		{
			this.task = task;
		}

		public String call() throws Exception
		{
			// TODO Auto-generated method stub
			Intent intent = task.baseIntent;
			if (task.origActivity != null)
			{
				intent.setComponent(task.origActivity);
			}

			// Skip home activity
			if (intent.hasCategory(Intent.CATEGORY_HOME))
			{
				//removeList.add(task);
				return null;
			}

			final ResolveInfo info = pm.resolveActivity(intent, 0);
			if (info == null)
				return null;

			//if (!DBHelper.queryInRecentByPKG(task.baseIntent.getComponent().getClassName()))
			if (nir.contains(intent.getComponent().getPackageName(), intent.getComponent().getClassName()))
				return null;

			/*for (String name : exceptionList)
				if (task.baseIntent.getComponent().getPackageName().compareTo(name) == 0)
				{
					removeList.add(task);
					break;
				}*/
			//}
			taskList.add(task);
			infoList.add(info);
			return null;
		}

	}

	public int getCount()
	{
		// TODO Auto-generated method stub
		if (pkgList != null)
			return taskList.size() + pkgList.size();
		else
			return taskList.size();
	}

	public Object getItem(int arg0)
	{
		// TODO Auto-generated method stub
		if (arg0 < taskList.size())
			return taskList.get(arg0);
		else
			return pkgList.get(arg0 - taskList.size());
	}

	public long getItemId(int arg0)
	{
		// TODO Auto-generated method stub
		return arg0;
	}

	public View getView(int position, View convertView, ViewGroup parent)
	{
		Wrapper wrapper;

		if (convertView == null)
		{
			LayoutInflater inflater = mCtx.getLayoutInflater();

			convertView = inflater.inflate(R.layout.item, null);
			wrapper = new Wrapper();
			wrapper.icon = (ImageView) convertView.findViewById(R.id.icon);
			wrapper.text = (TextView) convertView.findViewById(R.id.name);

			convertView.setTag(wrapper);
		} else
		{
			wrapper = (Wrapper) convertView.getTag();
		}

		if (position < taskList.size())
		{
			ResolveInfo ri = infoList.get(position);

			if (IconCache.icons.containsKey(ri.loadLabel(pm)))
			{
				wrapper.icon.setImageBitmap(IconCache.icons.get(ri.loadLabel(pm)));
			} else
				wrapper.icon.setImageDrawable(ri.loadIcon(pm));
			//wrapper.icon.setTag(position);
			//wrapper.icon.setOnTouchListener(this);
			//wrapper.icon.setOnLongClickListener(this);
			wrapper.text.setText(ri.loadLabel(pm));
		} else
		{
			App app = pkgList.get(position - taskList.size());
			String label = app.getLabel();
			if (IconCache.icons.containsKey(label))
			{
				wrapper.icon.setImageBitmap(IconCache.icons.get(label));
			} else
			{
				Cursor cursor = DBHelper.queryIcon(label);
				new LoadTask(wrapper.icon, cursor, label).execute();
			}

			wrapper.text.setText(label);
		}
		return convertView;
	}

}
